package com.example.gcmtest1.httpserver;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import org.apache.http.HttpException;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.impl.DefaultHttpServerConnection;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.HttpRequestHandlerRegistry;
import org.apache.http.protocol.HttpService;

import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;

public class WebServer extends Thread {

	private Context context;
	
	private String logName = "WebServer";
	
	private boolean isRunning = false;
	private BasicHttpProcessor httpProc;
	private BasicHttpContext httpContext;
	private HttpService httpService;
	private HttpRequestHandlerRegistry registry = null;
	
	public WebServer(Context context) {
		this.context = context;
		
		this.httpProc = new BasicHttpProcessor();
		this.httpContext = new BasicHttpContext();
		
		this.httpService = new HttpService(this.httpProc, new DefaultConnectionReuseStrategy(), 
				new DefaultHttpResponseFactory());
						
		this.registry = new HttpRequestHandlerRegistry();
		this.registry.register("/q/*", new MyHandler1());
		
		this.httpService.setHandlerResolver(this.registry);
		
		String ipStt = "";
		try {
			ipStt = this.getWiFiIPAddress();
			Log.i(logName, "Listening at IP:" + ipStt);
		} catch (Exception e) {
			Log.e(logName, "Cannot get IP Address from Wifi");
			Log.e(logName, e.toString());
		}
		
	}
	
	public String getWiFiIPAddress() {
		WifiManager myWifiManager = (WifiManager) this.context.getSystemService(Context.WIFI_SERVICE);
		WifiInfo myWifiInfo = myWifiManager.getConnectionInfo();
		int myIp = myWifiInfo.getIpAddress();
		int intMyIp3 = myIp/0x1000000;
		int intMyIp3mod = myIp%0x1000000;
	      
		int intMyIp2 = intMyIp3mod/0x10000;
		int intMyIp2mod = intMyIp3mod%0x10000;
	      
		int intMyIp1 = intMyIp2mod/0x100;
		int intMyIp0 = intMyIp2mod%0x100;		
		String ipStt = String.valueOf(intMyIp0)
		         + "." + String.valueOf(intMyIp1)
		         + "." + String.valueOf(intMyIp2)
		         + "." + String.valueOf(intMyIp3);
		         
		return(ipStt);
	}
	
    @Override
    public void run() {
    	super.run();
                
    	try {
    		ServerSocket serverSocket = new ServerSocket(7778);
                    
    		serverSocket.setReuseAddress(true);
    		
        
    		while(this.isRunning){
    			try {
    				Socket socket = serverSocket.accept();
    				
    				    				
    				/*
    				DefaultHttpServerConnection serverConnection = new DefaultHttpServerConnection();
    				                
    				serverConnection.bind(socket, new BasicHttpParams());
    				    				
    				BasicHttpContext httpCtx = new BasicHttpContext();
    				httpCtx.setAttribute("Socket", socket);
    				httpCtx.setAttribute("ServerConnection", serverConnection);
    				
    				this.httpService.handleRequest(serverConnection, httpCtx);
    				  				                                        				
    				serverConnection.shutdown();
    				*/
    				
    				Log.d(logName, "ServerSocket: Got New Accept, hashCode:" + String.valueOf(socket.hashCode()));
    				
    				//SingleRequestHandler s = new SingleRequestHandler(socket, this.httpService);    				
    				//s.startThread();
    				
    				HttpBuilder hb = new HttpBuilder(this.context, socket);
    				hb.startThread();
    				
    				
    			} catch (IOException e) {
    				e.printStackTrace();
//    			} catch (HttpException e) {
//    				e.printStackTrace();
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
                    
    		serverSocket.close();
    	} 
    	catch (IOException e) {
    		e.printStackTrace();
    	}
    }
    
    public synchronized void startThread() {
    	isRunning = true;
            
    	super.start();
    }	
}
